﻿//#define DEBUG_BG

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Interop;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Effects;
using System.Windows.Media.Converters;
using System.Windows.Media.Composition;
using System.Windows.Media.Animation;
using System.Windows.Media.Media3D;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Runtime.InteropServices;

namespace GadgetBase
{

    public abstract class GadgetWindow : DragedWindow
    {
        private Grid grid;
        private DoubleAnimation activateAnimation;
        private DoubleAnimation disableAnimation;
        private SystemButtonPanel systemButtonPanel = new SystemButtonPanel();
        private bool docked = false;
        private double width = 100;
        private BitmapImage logoImage;

        public UIElementCollection Children 
        {
            get
            {
                return grid.Children;
            }
        }
        public bool Docked
        {
            get
            {
                return this.docked;
            }
            set
            {
                this.docked = value;
                this.systemButtonPanel.SizeMode = (this.docked ? SizeMode.Small : SizeMode.Large);                
                this.grid.ColumnDefinitions[1].Width = new GridLength(this.systemButtonPanel.Width);
                SetWidth();
            }
        }
        public new double Width
        {
            get
            {
                return this.width - this.grid.ColumnDefinitions[1].Width.Value;                
            }
            set
            {
                OnChangeWidth(value);
            }
        }
        public BitmapImage LogoImage 
        {
            get
            {
                return this.logoImage;
            }
        }

        protected virtual string LogoImagePath 
        {
            get
            {
                return "DefaulGadgetIcon.png";
            }
        }

        private void SetWidth()
        {
            base.Width = this.width + this.systemButtonPanel.Width;
        }
        private void OnChangeWidth(double width)
        {
            this.width = width;
            base.Width = this.width + this.grid.ColumnDefinitions[1].Width.Value;
        }

        public event GadgetWindowEventHandler SettingsShowing;
        public event GadgetWindowEventHandler3 Drop;
        public event GadgetWindowEventHandler3 BeginDrag;        

        public GadgetWindow()
        {
            this.logoImage = GlobalMethods.GetBitmapImage(GlobalMethods.GetFullPath(this.LogoImagePath));

            base.Height = 97;
            base.Width = 147;
            
            Grid grid = new Grid();            
            ColumnDefinition column1 = new ColumnDefinition();
            column1.Width = GridLength.Auto;
            ColumnDefinition column2 = new ColumnDefinition();
            column2.Width = new GridLength(25);
            grid.ColumnDefinitions.Add(column1);
            grid.ColumnDefinitions.Add(column2);
            base.Content = grid;

            base.ShowInTaskbar = false;
            base.WindowStyle = WindowStyle.None;            
#if DEBUG_BG
            base.Background = Brushes.Green;
#else            
            base.AllowsTransparency = true;
            base.Background = Brushes.Transparent;            
#endif
            base.SnapsToDevicePixels = true;            

            this.MouseEnter += new MouseEventHandler(GadgetWindow_MouseEnter);
            this.MouseLeave += new MouseEventHandler(GadgetWindow_MouseLeave);
            this.MouseLeftButtonDown += new MouseButtonEventHandler(GadgetWindow_MouseLeftButtonDown);
            this.moveTo += new MoveToEventHandler(this_moveTo);
            
            systemButtonPanel.Name = "sbp";
            systemButtonPanel.ResetSize();
            systemButtonPanel.Opacity = 0;
            systemButtonPanel.HorizontalAlignment = HorizontalAlignment.Right;
            systemButtonPanel.VerticalAlignment = VerticalAlignment.Top;
            systemButtonPanel.CloseButtonClick += new GadgetWindowEventHandler(SystemButtonPanel_CloseButtonClick);
            systemButtonPanel.SettingsButtonClick += new GadgetWindowEventHandler(SystemButtonPanel_SettingsButtonClick);
            systemButtonPanel.DragPanelMouseLeftButtonDown += new MouseButtonEventHandler(SystemButtonPanel_DragPanelMouseLeftButtonDown);           

            this.grid = this.Content as Grid;
            this.grid.ColumnDefinitions[1].Width = new GridLength(this.systemButtonPanel.Width);
            SetWidth();
            
            Grid.SetColumn(systemButtonPanel, 1);
            this.grid.Children.Add(systemButtonPanel);
            activateAnimation = new DoubleAnimation(0, 1, TimeSpan.FromSeconds(0.2), FillBehavior.HoldEnd);
            disableAnimation = new DoubleAnimation(1, 0, TimeSpan.FromSeconds(0.5), FillBehavior.HoldEnd);
        }
        public GadgetWindow(String imageUrl)
            :this()
        {
            SetBackground(imageUrl);
        }

        public GadgetWindow(ImageSource image)
            :this()
        {
            SetBackground(image);                        
        }

        public void SetBackground(String imageUrl)
        {
            SetBackground(GlobalMethods.GetBitmapImage(imageUrl));
        }

        public void SetBackground(ImageSource image)
        {
            this.Background = new ImageBrush(image);
            this.Height = image.Height;
            this.Width = image.Width;
        }

        private void GadgetWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            //GadgetWindow o = this as GangetWindow;
            //DragDropEffects dropEffect = DragDrop.DoDragDrop(this, o, DragDropEffects.All | DragDropEffects.Link);
        }

        protected override void OnDrop()
        {
            this.x = this.RestoreBounds.X;
            this.y = this.RestoreBounds.Y;

            base.OnDrop();
            if (this.Drop != null)
            {
                this.Drop(this);
            }
        }

        private void SystemButtonPanel_DragPanelMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            OnMouseLeftButtonDown(e);
        }


        //protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        //{
        //    base.OnMouseLeftButtonUp(e);

        //    base.OnLocationChanged(e);
        //}                


        void closeLabel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.Close();
        }


        void settingsLabel_MouseLeftButtonDown
            (object sender, MouseButtonEventArgs e)
        {
            OnSettingsShowing();
        }

        protected virtual void OnSettingsShowing()
        {
            GadgetSettingsWindow settingsWindow = new GadgetSettingsWindow();
            settingsWindow.Owner = this;
            settingsWindow.Show();            
            if(SettingsShowing != null)
            {
                SettingsShowing();
            }
        }

        private void SystemButtonPanel_CloseButtonClick()
        {
            this.Close();
        }


        private void SystemButtonPanel_SettingsButtonClick()
        {
            OnSettingsShowing();
        }


        private void GadgetWindow_MouseEnter(object sender, MouseEventArgs e)
        {
            systemButtonPanel.BeginAnimation(SystemButtonPanel.OpacityProperty, activateAnimation);            
        }
        private void GadgetWindow_MouseLeave(object sender, MouseEventArgs e)
        {
            systemButtonPanel.BeginAnimation(SystemButtonPanel.OpacityProperty, disableAnimation);
        }


        private double x = -1;
        private double y = -1;

        private bool IsMoving(double x, double y)
        {
            return (this.x == x && this.y == y);
        }

        public void MoveTo(double x, double y)
        {
            OnMoveTo(x, y);
        }

        private void BeginAnimation(DoubleAnimation x, DoubleAnimation y)
        {
            this.BeginAnimation(Window.TopProperty, y);
            this.BeginAnimation(Window.LeftProperty, x);
        }

        private delegate void MoveToEventHandler(double x, double y);
        private event MoveToEventHandler moveTo;
        private void this_moveTo(double x, double y)
        {
            if (!IsMoving(x, y))
            {
                DoubleAnimation xAnimation = new DoubleAnimation(this.RestoreBounds.X, x, TimeSpan.FromSeconds(0.2), FillBehavior.HoldEnd);
                DoubleAnimation yAnimation = new DoubleAnimation(this.RestoreBounds.Y, y, TimeSpan.FromSeconds(0.2), FillBehavior.HoldEnd);


                this.x = x;
                this.y = y;
                this.BeginAnimation(xAnimation, yAnimation);
            }
        }

        private void OnMoveTo(double x, double y)
        {
            if (moveTo != null)
            {
                moveTo(x, y);
            }
        }

        public void Move(double dx, double dy)
        {
            MoveTo(this.RestoreBounds.X + dx, this.RestoreBounds.Y + dy);
        }

        protected override void OnBeginDrag()
        {
            base.OnBeginDrag();
            if (this.BeginDrag != null)
            {
                this.BeginDrag(this);
            }
        }
    }
}
